package com.bosicloud.cmb.ibp.api.manager.util;

import com.bosicloud.cmb.ibp.api.manager.commom.model.IbpApiDocs;
import com.bosicloud.cmb.ibp.api.manager.commom.vo.IbpApiDocsVO;
import io.swagger.models.HttpMethod;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import java.util.*;
import java.util.stream.Stream;

public class PathsProcessor {


    private final Swagger swagger;

    private final OperationProcessor operationProcessor;

    public PathsProcessor(Swagger swagger) {
        this.swagger = swagger;
        this.operationProcessor = new OperationProcessor(swagger);
    }

    public List<IbpApiDocsVO> processPaths() {
        List<IbpApiDocsVO> ibpApiDocsVOList = new ArrayList<>();
        final Map<String, Path> pathMap = swagger.getPaths();
        pathMap.forEach((pathStr, paths) -> {
            Map<HttpMethod, Operation> operationMap = paths.getOperationMap();
            operationMap.forEach((httpMethod, operation) -> {
                String method = httpMethod.name();
                IbpApiDocsVO ibpApiDocsVO = new IbpApiDocsVO();
                IbpApiDocs apiDocs = IbpApiDocs.builder()
                        .returnType(getMediaType())
                        .name(StringUtils.defaultIfEmpty(operation.getSummary(), method + pathStr))
                        .method(method)
                        .path(pathStr)
                        .build();
                BeanUtils.copyProperties(apiDocs, ibpApiDocsVO);
                ibpApiDocsVO.setIbpApiDocParamsList(operationProcessor.processor(operation));
                ibpApiDocsVO.setResponseMessagesVOList(operationProcessor.processorResponseMessages(operation));
                ibpApiDocsVOList.add(ibpApiDocsVO);

            });

        });

        return ibpApiDocsVOList;
    }

    private String getMediaType() {
        return Optional.ofNullable(swagger.getProduces())
                .map(Collection::stream)
                .flatMap(Stream::findAny)
                .filter(StringUtils::isNotEmpty)
                .orElse("application/json");
    }
}
